package com.white.loggerserver.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import com.white.loggerserver.R;
import com.white.loggerserver.utils.UiHelper;

import java.util.ArrayList;
import java.util.List;

/**
 * @author ytf
 * Created by on 2021/04/24 17:47
 */
public class MySpinner extends RelativeLayout
{
    private float textSize = 0f;
    private int textColor = 0;
    private String defaultStr;

    private int contentWidth = 0;
    private TextView tv;
    private ImageView arrow;
    private SpinnerItemListener mSpinnerItemListener;
    private Pop mPop;
    private List<SpinnerItem> items = new ArrayList<>();

    public MySpinner(Context context)
    {
        this(context, null);
    }

    public MySpinner(Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);
    }

    public MySpinner(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MySpinner);
        textColor = ta.getColor(R.styleable.MySpinner_msp_content_txt_color, Color.BLACK);
        textSize = ta.getDimension(R.styleable.MySpinner_msp_content_txt_size, 20f);
        defaultStr = ta.getString(R.styleable.MySpinner_msp_content_default);
        contentWidth = ta.getDimensionPixelSize(R.styleable.MySpinner_msp_content_width, 0);
        ta.recycle();

        createView(context);
    }

    private void createView(Context context)
    {

        LayoutParams pi = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        pi.leftMargin = 15;
        arrow = new ImageView(context);
        arrow.setImageResource(R.drawable.ic_arrow_down);
        pi.addRule(CENTER_VERTICAL);
        pi.addRule(ALIGN_PARENT_END);
        arrow.setId(R.id.spinner_arrow_id);
        addView(arrow, pi);

        LayoutParams p = new LayoutParams(contentWidth == 0 ? LayoutParams.WRAP_CONTENT :
                contentWidth == -1 ? LayoutParams.MATCH_PARENT : contentWidth, LayoutParams.WRAP_CONTENT);
        tv = new TextView(context);
        tv.setId(R.id.spinner_txt_id);
        tv.getPaint().setTextSize(textSize);
        tv.setGravity(Gravity.START);
        tv.setTextColor(textColor);
        tv.setText(defaultStr);
        p.addRule(LEFT_OF, R.id.spinner_arrow_id);
        p.addRule(ALIGN_PARENT_START);
        p.addRule(CENTER_VERTICAL);
        addView(tv, p);
    }

    public int getCurrentIndex()
    {
        return currentIndex;
    }

    public void disable(String tip){
        tv.setTextColor(Color.GRAY);
        tv.setText(tip);
        arrow.setVisibility(View.INVISIBLE);
    }

    public void config(int selectedIndex, SpinnerItemListener itemListener, Iterable<INameProvider> strs)
    {
        currentIndex = selectedIndex;
        mSpinnerItemListener = itemListener;
        items.clear();
        int i = 0;
        for (INameProvider p : strs)
        {
            items.add(new SpinnerItem(i, p.getStr(), selectedIndex == i));
            if (selectedIndex == i)
            {
                tv.setText(p.getStr());
            }
            i++;
        }
        bindEvent();
        mSpinnerItemListener.onClick(items.get(selectedIndex));
    }

    public void config(int selectedIndex, SpinnerItemListener itemListener, String[] strs)
    {
        currentIndex = selectedIndex;
        mSpinnerItemListener = itemListener;
        items.clear();
        int i = 0;
        for (String str : strs)
        {
            items.add(new SpinnerItem(i, str, selectedIndex == i));
            if (selectedIndex == i)
            {
                tv.setText(str);
            }
            i++;
        }
        bindEvent();
        mSpinnerItemListener.onClick(items.get(selectedIndex));
    }

    public void config(int selectedIndex, SpinnerItemListener itemListener, List<String> strs)
    {
        currentIndex = selectedIndex;
        mSpinnerItemListener = itemListener;
        items.clear();
        int i = 0;
        for (String str : strs)
        {
            items.add(new SpinnerItem(i, str, selectedIndex == i));
            if (selectedIndex == i)
            {
                tv.setText(str);
            }
            i++;
        }
        bindEvent();
        mSpinnerItemListener.onClick(items.get(selectedIndex));
    }

    private void bindEvent()
    {
        setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if (mPop == null)
                {
                    mPop = new Pop(getContext(), items);
                }
                if (mPop.isShowing())
                {
                    mPop.dismiss();
                } else
                {
                    expandArrow();
                    mPop.show();
                }
            }
        });
    }

    private void shrinkArrow()
    {
        ViewCompat.animate(arrow)
                .rotation(0f)
                .setDuration(500L)
                .setInterpolator(new DecelerateInterpolator())
                .start();
    }

    private void expandArrow()
    {
        ViewCompat.animate(arrow)
                .rotation(180f)
                .setDuration(500L)
                .setInterpolator(new AccelerateInterpolator())
                .start();
    }


    public void release()
    {
        if (mPop != null)
        {
            mPop.dismiss();
            mPop = null;
        }
        mSpinnerItemListener = null;
    }



    private int currentIndex;
    private class Pop
    {
        private Context context;
        private List<SpinnerItem> datas;

        private PopupWindow pop;
        private Adapter adapter;

        public Pop(Context context, List<SpinnerItem> datas)
        {
            this.context = context;
            this.datas = datas;
            onCreate();
        }

        private void onCreate()
        {
            RecyclerView contentView = new BorderStyleRecycleView(context);
            pop = new PopupWindow(contentView, MySpinner.this.getWidth(), ViewGroup.LayoutParams.WRAP_CONTENT, true);
            pop.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
//            pop.contentView.systemUiVisibility = (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_FULLSCREEN)
            pop.setTouchable(true);
            pop.setOutsideTouchable(true);
            pop.setOnDismissListener(new PopupWindow.OnDismissListener()
            {
                @Override
                public void onDismiss()
                {
                    shrinkArrow();
                }
            });
            contentView.setLayoutManager(new LinearLayoutManager(context));
            adapter = new Adapter(datas);
            contentView.setAdapter(adapter);
            adapter.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
                    for (SpinnerItem s : datas)
                    {
                        s.isSelected = false;
                    }
                    datas.get(position).isSelected = true;
                    adapter.notifyDataSetChanged();
                    currentIndex = position;
                    tv.setText(datas.get(position).str);
                    mSpinnerItemListener.onClick(datas.get(position));
                    dismiss();
                }
            });
        }

        public void dismiss()
        {
            if (pop.isShowing())
                pop.dismiss();
        }

        public boolean isShowing()
        {
            return pop.isShowing();
        }

        public void show()
        {
            int yOffset = UiHelper.dpToPx(context, 10f);
            if (Build.VERSION.SDK_INT == 24)
            {
                Rect visibleFrame = new Rect();
                MySpinner.this.getGlobalVisibleRect(visibleFrame);
                int height = MySpinner.this.getResources().getDisplayMetrics().heightPixels - visibleFrame.bottom;
                pop.setHeight(height);
                pop.showAsDropDown(MySpinner.this, 0, yOffset);
            } else
            {
                pop.showAsDropDown(MySpinner.this, 0, yOffset);
            }
            adapter.notifyDataSetChanged();
        }
    }

    private class Adapter extends BaseQuickAdapter<SpinnerItem, BaseViewHolder>
    {

        public Adapter(@Nullable List<SpinnerItem> data)
        {
            super(R.layout.item_spinner_single_txt, data);
        }

        @Override
        protected void convert(BaseViewHolder helper, SpinnerItem item)
        {
            TextView tv = helper.getView(R.id.title);
            tv.getPaint().setTextSize(textSize);
            if (item.isSelected)
            {
                helper.setBackgroundResource(R.id.title, R.drawable.sp_single_selected);
                helper.setTextColor(R.id.title, Color.WHITE);
            } else
            {
                helper.setBackgroundResource(R.id.title, R.drawable.sp_single_unselected);
                helper.setTextColor(R.id.title, Color.BLACK);
            }
            helper.setText(R.id.title, item.str);
        }
    }

    public interface SpinnerItemListener
    {
        void onClick(SpinnerItem item);
    }

    public interface INameProvider
    {
        String getStr();
    }

    public static class SpinnerItem
    {
        public int index;
        public String str;
        public boolean isSelected;

        public SpinnerItem(int index, String str, boolean isSelected)
        {
            this.index = index;
            this.str = str;
            this.isSelected = isSelected;
        }
    }
}
